<?php 

#sing ('News_Usenet_NNTP');
using ('News_UI_YAxisRotate');
define ('PICTURE_SIZE', 240);
define ('PICTURE_FONT', 'verdanab.ttf');
define ('BUTTON_FONT', 'LucidaGrande.ttf');

function ratio($im, $fill=NULL, $ov=NULL)
{
	$w=imagesx($im);$h=imagesy($im);$r=$w/$h;$d=PICTURE_SIZE;
	if($ov) $d=$ov;
	$condition=$fill?$w<$h:$w>$h;
	return $condition 
	       ? array('x'=>$d,'y'=>$d / $r, 'w'=>$w, 'h'=>$h)
		   : array('y'=>$d,'x'=>$d * $r, 'w'=>$w, 'h'=>$h);
}

class News_UI_Image
{
    var $Group;
    var $Id;
    var $Controller;
    var $Dir;
    var $Awake;
    var $NNTP;
    var $Yenc;
    var $Encoding = NULL;
    
    function News_UI_Image($controller, $connect = true)
    {
        $this->Controller = $controller;
        $this->Awake      = $connect;
        $this->Group      = $controller->Settings['group'];
        if (isset($controller->Settings['id']))
        {
            $this->Id = $controller->Settings['id'];
        }
        $this->NNTP       = $this->Controller->Server->NNTP;
        $this->Dir        = './data/temp/' . $this->Group;
        if (! is_dir ($this->Dir)) 
        {
            mkdir ($this->Dir);
        }
    }
    
    function Connect ()
    {      
        if (!$this->NNTP->connect())                                                
        {                                                
            echo "Unable to connect!";                                             
            return false;                                               
        }  
        
		if ( ! ( $gi=$this->NNTP->join_group(trim($this->Group)) ) )                    
		{
		    echo "Unable to join group [$this->Group]";  
		    $this->Disconnect();
			return false;
		}   
        return $gi;
    }
    
    function Disconnect()
    {
        $this->NNTP->quit();
    }
    
    

    function Run($Command, $Priority = 0)
    { 
        if($Priority)
            $PID = shell_exec("nohup nice -n $Priority $Command > /dev/null & echo $!");
        else
            $PID = shell_exec("nohup $Command > fn.txt & echo $!");
        return($PID);
    }

    function IsRunning($PID)
    { 
	    exec("ps $PID", $ProcessState);
	    return(count($ProcessState) >= 2);
    }
    
    function DownloadArticlesEx ($id, $group, $message = '', $count = 8)
    {
        $dir     = "data/" . time();
        mkdir ($dir);
        $thread  = array(); 
        $params  = array();
        $tmp     = array();
        $ret     = array();
        $keys    = explode ('-', $id);
        $size    = sizeof($keys);
        $span    = ceil ($size / THREAD_COUNT);      
        $bytes   = 0;
        $time    = time();
        
        for ($i=0;$i<sizeof($keys);$i++)
        {
            $tmp[] = $keys[$i]; 
            if (sizeof($tmp) == $span)
            {
                $params[] = implode('-', $tmp);
                $tmp = array();
            }
        }
        
        if (sizeof($tmp) > 0)
        {
            $params[] = implode('-', $tmp); 
        }
         
        for ($i=0;$i<sizeof($params);$i++)
        {
            $param    = $params[$i];
            $command  = "php index.php t $group $param $dir $i";
            echo $command . "\n";
            $thread[] = $this->Run ($command);
        }
         
        while (true)
        {
             $run = false;
             for ($i=0;$i<sizeof($thread);$i++)
             {
                 $run     = $run || $this->IsRunning($thread[$i]);
             }
                 $elapsed = time() - $time;
                 $count   = sizeof(scandir($dir)) - 2;
                 echo ". $count of $size ($elapsed) {$message}\n";
	          	 $this->Controller->LogEntry ("{$elapsed}. Checking thread", $count, $size, $group);
                 sleep(2);
                 
             if (!$run) break;
        } 
        
        for ($x=0;$x<sizeof($keys);$x++)
        {
            $path   = $dir . '/' . $keys[$x] . '.news'; 
            $body   = $this->Controller->Read ($path);
            $bytes += filesize($path);
            $ret[]  = $body;        
                                                    
            if (strpos($body, "ybegin") !== false)                                             
            {  
                $this->Yenc = true;                            
            }                               
        }  
        
        $time = time() - $time;
        $per  = ceil ( $bytes/$time/1000 );
        echo "$bytes bytes in $time secs ($per kb/s).\n";
        
        exec ("rm -rf $dir");
        
        return $ret;
    }
    
    function DownloadArticles ($id = '', $log = false, $msg = NULL, $dest = NULL)
    {      
       # echo "Incoming id #{$id}\n";
        if (strlen($id) > 0) $this->Id = $id;
		$messages = array();
		$ids      = explode ('-', $this->Id);  
		
		$caption  = $msg ? $msg : 'Downloading articles';
 
        if ($this->Awake)
        {
            $this->Connect();
        }
        
		for ($i=0;$i<sizeof($ids);$i++)
		{
            $message = $this->NNTP->get_article($ids[$i]);   
            if ($dest)
            {
                $content  = $this->Assemble (array($message)); 
                $path     = $dest . '/' . $ids[$i] . '.news';
                echo "Saving $i to {$path}\n";
                $this->Controller->Save($path, trim($content[0]['body']));
            }
            else if ($log)
            {
                $p = ceil(($i+1)/sizeof($ids) * 100) . '%';
		        echo "{$caption} {$p}\n";
		        $this->Controller->LogEntry ("{$caption} " . $ids[$i], $i + 1, sizeof($ids), $this->Group, $index);
            }
            $messages[] = $message;
		}
        echo "\n"; 
        
        if ($this->Awake)
        {
            $this->Disconnect();
        }
        
        return $messages;
    }
    
    function ImageCreate($filename)
    {
        $im = @imagecreatefromjpeg ($filename);
        if (!$im) $im = @imagecreatefromgif ($filename);
        if (!$im) $im = @imagecreatefrompng ($filename);
        return $im;
    }
    
    function Resize ()
    {    
        $name = $this->Controller->Settings['name'];
        $name = str_replace ("^", '/', $name);
        $this->Thumbnail ($name);
    }
    
    function Thumbnail ($name = NULL)
    {    
        $b64 = base64_encode ($this->Id);
        $filename = $name ? $name : "data/temp/{$this->Group}/{$b64}"; 
        
        if (!file_exists(($filename)))
        {
            $filename = $this->Controller->GetArticle($this->Group, $this->Id);
        } 

        $im = $this->ImageCreate ($filename);
//        if (!$im) $im = @imagecreatefromgif ($filename);
//        if (!$im) $im = @imagecreatefrompng ($filename);
        if (!$im) 
        {
            $im = imagecreate (200,200);
            $tmp   = explode ('/', $filename);
            $white = imagecolorallocate ($im, 255, 255, 255);
            $black = imagecolorallocate ($im, 0,0,0);
		    imagettftext($im,  9, 0, 10, 16, $black , BUTTON_FONT, 'Unable to load image'); 
		    imagettftext($im,  9, 0, 10, 28, $black , BUTTON_FONT, array_pop($tmp)); 
        }
        if ($im)
        {
        	if ($this->Controller->Settings['thumb']=='large')
			{
				header("Content-Type: image/jpeg"); 
	//            imagejpeg ($dest,$thumbname,100);
	            imagejpeg ($im, "", 100);
	            imagedestroy ($im);
				return;
			} 
            $sz = ratio ($im);
			$dest = imagecreatetruecolor ($sz['x'], $sz['y']);
		    imagecopyresized($dest,$im,  0, 0, 0, 0, $sz['x'], $sz['y'], $sz['w'], $sz['h']);
//		    $white = imagecolorallocate ($dest, 255, 255, 255);
//		    imagettftext($dest,  12, 0, 10, 10, $white , PICTURE_FONT, "actual");
            header("Content-Type: image/jpeg"); 
//            imagejpeg ($dest,$thumbname,100);
            imagejpeg ($dest, "", 100);
            imagedestroy ($im);
            imagedestroy ($dest);
            return;
        }
        
        echo "Could not load $filename";
    }
    
    function GetFiles ($dir, $in = NULL, $filter = NULL, $collate = NULL)
    {  
        $ret = $in ? $in : array();
        if (is_dir($dir)) {
            if ($dh = opendir($dir)) {
                while (($file = readdir($dh)) !== false) {
                    if (!($file=='.' || $file=='..'))
                    {
                        if ($filter == NULL || strpos($file, $filter) !==false)
                        {
                            $ret[] = $dir . '/' . $file;
//                            break;
                        }
                    }
                }
                closedir($dh);
            }
        } 
    
	        for($x = 0; $x < sizeof($ret); $x++) {
			  for($y = 0; $y < sizeof($ret); $y++) {
			    if(filemtime($ret[$x]) > filemtime($ret[$y])) {
			      $hold = $ret[$x];
			      $ret[$x] = $ret[$y];
			      $ret[$y] = $hold;
			    }
			  }
			}
        
        $tmp = array();
        for ($i=0;$i<sizeof($ret)&&$i<50;$i++) $tmp[]=$ret[$i];
        
        if ($collate)
        {
            for ($i=50;$i<sizeof($ret);$i++) unlink ($ret[$i]);
        }
        
        return $tmp;
    }
    
    function Animate ($front, $back)
    {
        $arr=array(array('x'=>80,'y'=>320,'z'=>80),array('x'=>-80,'y'=>-320,'z'=>-80));
        $w = time() % 2;
        $f = $arr[$w];
        
                     $__i = array();
                     $__x = array();
                     $__y = array();
                     $__d = array();
                     for ($i=$f['x'];$i!=$f['y'];$i+=$f['z'])
                     {
                         $fr = imagecreatetruecolor(PICTURE_SIZE,PICTURE_SIZE);
                         imagecopyresized($fr,$back, 0, 0, 0, 0, PICTURE_SIZE,PICTURE_SIZE,PICTURE_SIZE,PICTURE_SIZE); 
                         imagecopyresized($fr,$front, 0, $i, 0, 0, PICTURE_SIZE,PICTURE_SIZE,PICTURE_SIZE,PICTURE_SIZE); 
                         
				  	 ob_start();
					 imagegif($fr); 
					 $__i[] = ob_get_contents();
					 ob_end_clean();
                         $__x[] = 0;
                         $__y[] = 0;
                         $__d[] = 5;
                         imagedestroy($fr); 
                     } 
                     
                 header("Content-Type: image/gif"); 
                     $gifmerge    = new GifMerge($__i, 1, 1, 1, 0, $__d, 2, $__x, $__y, 'C_MEMORY');
                     echo $gifmerge -> getAnimation();    
    
    }
    
    function Progress () 
    {  
        $picture = $this->ImageCreate ( $this->Controller->Jpg );
        if (!$picture)
        {
            $picture = imagecreate (400, 100);
        }
        header("Content-Type: image/png"); 
        imagepng ($picture);
        imagedestroy ($picture);
    }
    
    function Button () 
    {  
        $caption    = $this->Controller->Settings['caption'];
        $icon       = $this->Controller->Settings['icon'];
        $width      = $this->Controller->Settings['width'];
		$picture    = NULL;
		$font_size  = 8;
        $box        = imagettfbbox($font_size, 0, BUTTON_FONT, $caption);
        $fwidth     = $box[2]-$box[0];
        $fheight    = $box[1]-$box[7];
//        print_r($box); exit;
        
        $sz         = array('w'=>$fwidth + 8, 'h'=>$fheight + 8, 'x'=>4, 'y'=>14);
        if (isset($icon))
        {
            $picture = $this->ImageCreate("images/{$icon}");
            $sz['w'] += imagesx ($picture) + 2;
            $sz['h']  = max($sz['h'], imagesy($picture) + 8);
            $sz['x'] += imagesx ($picture) + 2; 
        }
        
        $sz ['y'] = 5 + ($sz['h'] / 2);
//        print_r($sz); exit;
        $button     = imagecreatetruecolor ($sz['w'], $sz['h']);
//        $button     = imagecreate (200,200);
        $white      = imagecolorallocate($button, 255,255,255);
        $gray       = imagecolorallocate($button, 125,125,125);
        $fill       = imagecolorallocate($button, 225,225,255);
        $red        = imagecolorallocate($button, 33,33,33);
        $off        = 2;
        imagefill ($button, $off,$off,$white);
        imagefilledrectangle ($button, $off,$off,$sz['w'] - $off, $sz['h'] - $off,$fill);
        if ($picture)
        {
            imagecopy($button, $picture, 4, 4, 0, 0, imagesx ($picture), imagesy ($picture));
            imagedestroy ($picture);
        }
        imagettftext($button,  $font_size, 0, $sz['x'], $sz['y'], $red , BUTTON_FONT, $caption); 
        imageline ($button, $off, $sz['h'] - $off, $sz['w'] - $off, $sz['h'] - $off, $gray);
        imageline ($button, $sz['w'] - $off, $off, $sz['w'] - $off, $sz['h'] - $off, $gray);
    //    ( resource $image , float $size , float $angle , int $x , int $y , int $color , string $fontfile , string $text [, array $extrainfo ] )
        header("Content-Type: image/png"); 
        imagepng ($button);
        imagedestroy ($button);
    }
    
    function Preview ($splash = NULL, $coords=NULL) 
    {  
    
        $dir        = "data/tube/{$this->Group}"; 
        $box        = $this->Controller->Settings['box'];
        $static     = $this->Controller->Settings['static'];
        $splashname = "data/temp/splash.jpeg";
        $frontname  = "data/temp/front{$box}.jpeg";
        $backname   = "data/temp/back{$box}.jpeg";
        if ($coords)
        { 
            $im   = $this->ImageCreate ($splashname);
            if ($im)
            {
                $dest = imagecreatetruecolor(PICTURE_SIZE,PICTURE_SIZE);
                $arr  = explode('x', $coords);
                $x    = PICTURE_SIZE * $arr[0];
                $y    = PICTURE_SIZE * $arr[1];
                $num  = ($arr[1] * 3) + $arr[0];
                $frontname  = "data/temp/front{$num}.jpeg";
                $backname   = "data/temp/back{$num}.jpeg";
                
                imagecopyresized($dest,$im, 0, 0, $x, $y, imagesx($im), imagesy($im), imagesx($im), imagesy($im));  
                
                if (file_exists($frontname) && strlen($static)==0)
                {
                     $src = $this->ImageCreate($frontname);
                     $this->Animate ($src, $dest); 
                     imagedestroy($src); 
                }
                else
                {
	                 header("Content-Type: image/jpeg"); 
	                 imagejpeg ($dest, "", 45);
                }
	            imagejpeg ($dest, $backname, 95);
                imagedestroy($im);
                imagedestroy($dest);
            }
            return;
        }
    
	    if (strlen($static)>0)
        {
             $src = $this->ImageCreate($frontname);
             imagejpeg($src,'', 100);
             imagedestroy($src); 
             return;
        }
        $images = $this->GetFiles($dir, NULL, '.jpeg', false);
        $images = $this->GetFiles($this->Dir, $images);  
	    
	    // try random image from list
		$cache = $images[rand(0, sizeof($images) - 1)];   
		
		if (file_exists($cache))
		{ 
			$im   = $this->ImageCreate ($cache); 
        
			if (! $im)
			{ // second try at valid image
			    $i = 0;
			    while ($i < sizeof($images) && !$im)
			    {
			        $cache = $images[rand(0, sizeof($images) - 1)]; 
			        $im = $this->ImageCreate ($cache); 
			        $i++;
			    }
			}
		
			$picsize =  $splash ? (PICTURE_SIZE * 3) : PICTURE_SIZE;
			
			$dest = $splash ? imagecreatetruecolor ($picsize, PICTURE_SIZE * 2) : imagecreatetruecolor (PICTURE_SIZE, PICTURE_SIZE);
			
			if ($im)
			{
				$sz   = ratio($im, true, $picsize); 
				imagecopyresized($dest,$im,  0, 0, 0, 0, $sz['x'], $sz['y'], $sz['w'], $sz['h']);
			}
		}
		$t=date ('m/d/y h:i:s', filemtime($cache));
		
		$tmp  = explode ('/', $cache);
		$bkey = array_pop($tmp);
		$bdir = array_pop($tmp);
		$chiron = NULL;
		
		if (strpos($cache,'temp'))
		{
		    $bkey = base64_decode($bkey);
		    $loc  = "data/{$this->Group}.xml";
		    $xml  = simplexml_load_file($loc);
		    $db   = $xml->xpath("//article[contains(id, '{$bkey}')]");  
		    if ($db && sizeof($db) > 0)
		    {
		        $chiron = $db[0]->subject;
		    }
		} else $chiron = $bkey;
		
		$red   = imagecolorallocate ($dest, 100, 100, 100);
		$white = imagecolorallocate ($dest, 255, 255, 255);
		$pos   = $splash ? array('x'=>14, 'y'=>44) :array('x'=>9, 'y'=>30);
		
		
		$a=array ('/alt/','/binaries/','/pictures/','/erotica/','/nospam/','/multimedia/');
		$b=array ('a','b','p','e','ns','mm');
		
		$caption = preg_replace($a, $b, $this->Group);
		
		
		
		$font_size = $splash ? 33 : 22;
        $bbox   = imagettfbbox($font_size, 0, PICTURE_FONT, $caption);
        $width  = $bbox[2]-$bbox[0];
		while ($width > $picsize - $pos['x'] - 5)
		{
		    $font_size--;
            $bbox   = imagettfbbox($font_size, 0, PICTURE_FONT, $caption);
            $width  = $bbox[2]-$bbox[0];
		}		    
//		echo 'eureka!';
//		exit;
		
		
		imagettftext($dest,  $font_size, 0, $pos['x'] + 1, $pos['y'] + 1, $red , PICTURE_FONT, $caption); 
		imagettftext($dest,  $font_size, 0, $pos['x'], $pos['y'], $white , PICTURE_FONT, $caption);        

		
        $bbox   = imagettfbbox(7, 0, BUTTON_FONT, $t);
        $width  = $bbox[2]-$bbox[0];
        $tx = imagesx($dest) - $width - 4;
        $ty = imagesy($dest) - 4;
                
		imagettftext($dest,  7, 0, $tx+1, $ty + 1, $white , BUTTON_FONT, $t);             
		imagettftext($dest,  7, 0, $tx, $ty, $red , BUTTON_FONT, $t);       
        
		if ($splash)
		{
		    $W = imagesx ($dest) - 80;
		    $H = imagesy ($dest) - 20;
		    $ent=array('/\&quot;/','/\&gt;/','/\&lt;/');$ht=array('"','>','<');
		    $chiron=preg_replace($ent,$ht,$chiron);
		    $arr  = explode (' ', $chiron);
		    $tmp  = array();
		    $line = '';
		    $sz   = 14;
		    for ($i=0;$i<sizeof ($arr);$i++)
		    {
		        $line  .= $arr[$i] . ' '; //{$i};
                $bbox   = imagettfbbox($sz, 0, PICTURE_FONT, $line.$arr[$i+1]);
                $width  = $bbox[2]-$bbox[0];
		        if ($width >= $W)
		        {
		            $tmp[] = $line;
		            $line = "";
		        }
		    }
		    if (strlen($line) > 0)
		    {
		        $tmp[] = $line;
		    }
		    
		    $s = $H - (sizeof($tmp) * 20); $x = 0;
		    for ($i=$s;$i<$H;$i+=20) 
		    {
		        imagettftext($dest,  $sz, 0, $pos['x']+1, $i+1, $red , PICTURE_FONT, $tmp[$x]);      
		        imagettftext($dest,  $sz, 0, $pos['x'], $i, $white , PICTURE_FONT, $tmp[$x]);      
		        $x ++;
		    }
		        
//		    imagettftext($dest,  9, 0, $pos['x'], $H - 20, $white , BUTTON_FONT, sizeof ($tmp));     
		} 
		
        ob_start();
        imagejpeg ($dest,"",100);
        $raw = ob_get_contents();
        ob_end_clean();
        
        
		if ($splash) 
		{
		    $this->Controller->Save($splashname, $raw);
		}
		else 
		{
		    $this->Controller->Save($frontname, $raw);
		}
		$this->Controller->Save(sprintf('%s.idx',$splash?$splashname:$frontname), $cache);
		
		
        if (file_exists($backname) && strlen($static)==0)
        {
             $src = $this->ImageCreate($backname);
             $this->Animate ($src, $dest);  
             imagedestroy($src); 
        }
		else if (file_exists($splashname) || !$splash) 
		{
            header("Content-Type: image/jpeg"); 
		
		    echo $raw; 
		}
		
		imagedestroy($im); 
		imagedestroy($dest);  

		return;
    }
    
    function Assemble ($messages)
    {
        $content = array();        
		for ($i=0;$i<sizeof($messages);$i++)     
		{             
		    $MIME_Message = $messages[$i];
		    if (!$MIME_Message)
		    {
		        continue;
		    }
            $header = $MIME_Message->get_main_header();                                               
            $parts  = $MIME_Message->get_all_parts();                                                                
            $count  = 0;   
            $this->Yenc   = false;                                       
            foreach ($parts as $part)                                              
            {              
                $subject = isset($part["header"]["subject"]) ? $part["header"]["subject"] : "";    
                if (isset($part['header']['content-transfer-encoding']) && 
                    strlen($part['header']['content-transfer-encoding']) > 0)
                {
                    $this->Encoding = $part['header']['content-transfer-encoding'];  
                }                                              
                $body    = $part["body"];                                              
                if ( (strpos($body, "ybegin") !== false) || (strpos(strtolower($subject), "yenc") !== false) )                                             
                { // YENC decoding  
                    $arr = array ();                                             
                    $arr["header"]     = array ("content-type"=>"image/jpeg", "content-transfer-encoding" => "yenc");                                             
                    $arr["body"]       = $part["body"];   
                    $this->Yenc      = true;                            
                }                                               
                $attachment_id = $count;                                           
                $count++;                                              
            }                                               

                                                        
            if ($MIME_Message->get_total_part() > $attachment_id)                                              
            {                                             
                $header = $MIME_Message->get_part_header($attachment_id);                                             
                $body   = $MIME_Message->get_part_body($attachment_id);                                             
                if (strcmp($header["content-type"],"") == 0)                                              
                {                                             
                    header("Content-Type: text/html");                                             
                    echo $messages_ini["error"]["request_fail"];                                             
                }                                              
                else                                              
                {                          
                    $content[] = $MIME_Message->get_part($attachment_id);
                }                                             
            }                                              
            else                                              
            {                                             
                header("Content-Type: text/html");                                             
                echo $messages_ini["error"]["multipart_fail"];                                             
            }  
		}    
		return $content;
    }

    function Display()
    {  // deprecated   
	    if ($this->Id == 'resize')
		{
		    $this->Resize();
		    return;
		}     
	    if ($this->Id == 'progress')
		{
		    $this->Progress();
		    return;
		}     
	    if ($this->Id == 'button')
		{
		    $this->Button();
		    return;
		}     
	    if ($this->Id == 'preview')
		{
		    $this->Preview();
		    return;
		}     
		if (isset($this->Controller->Settings['coords']))
		{
		    $this->Preview(true, $this->Controller->Settings['coords']);
		    return;
		}

	    if ($this->Id == 'splash')
		{
		    $this->Preview(true);
		    return;
		}     
		if (isset($this->Controller->Settings['thumb']))
		{
		    $this->Thumbnail();
		    return;
		}
		
		ob_start ();
		$filename = $this->Controller->GetArticle($this->Group, $this->Id);
		ob_end_clean();
        header("Content-Type: image/jpeg"); 
		echo $this->Read($filename);
    }
    
    function Read ($path)
    { 
        $fp = fopen($path, 'r');
        if ($fp)
        {
            $fr = fread ($fp, filesize($path));
            fclose($fp);
            return $fr;
        }
    }
    
    function Save ($path,$data)
    { 
        $fp = fopen($path, 'w');
        if ($fp)
        {
            fwrite ($fp, $data);
            fclose($fp);
            return;
        }
    }
}
 

